package com.information.manage.basic.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.information.manage.basic.common.result.Result;
import com.information.manage.basic.common.utils.RedisUtils;
import com.information.manage.basic.mapper.DepartmentMapper;
import com.information.manage.basic.mapper.LogInfoMapper;
import com.information.manage.basic.model.entity.DepartmentDO;
import com.information.manage.basic.model.entity.LogInfo;
import com.information.manage.basic.model.query.LogDeleteQuery;
import com.information.manage.basic.model.query.LogPageQuery;
import com.information.manage.basic.model.vo.DepartmentVisitStatisticVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 92110
 */
@RestController
@RequestMapping("/log")
@Api(tags = "日志管理")
public class LogInfoController {

    @Value("${base.statistic.visitInterface:/sys/user/login}")
    private String statisticVisitInterface;

    @Value("${base.departmentTypeCollection:1}")
    private Long departmentTypeCollection;

    @Resource
    private LogInfoMapper logInfoMapper;

    @Resource
    private DepartmentMapper departmentMapper;

    @Resource
    private RedisUtils redisUtils;

    private static final String departmentCacheKey = "department_info";


    @GetMapping("/list/page")
    @ApiOperation(value = "日志列表", notes = "日志列表")
    public Result<Page<LogInfo>> logInfoList(LogPageQuery logPageQuery) {
        LambdaQueryWrapper<LogInfo> logInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (logPageQuery.getUserId() != null) logInfoLambdaQueryWrapper.eq(LogInfo::getLogUserId, logPageQuery.getUserId());
        if (StringUtils.isNotEmpty(logPageQuery.getUserName())) logInfoLambdaQueryWrapper.like(LogInfo::getLogUser, logPageQuery.getUserName());
        if (StringUtils.isNotEmpty(logPageQuery.getRequestAddr())) logInfoLambdaQueryWrapper.like(LogInfo::getRequestAddress, logPageQuery.getRequestAddr());
        if (StringUtils.isNotEmpty(logPageQuery.getIpAddr())) logInfoLambdaQueryWrapper.like(LogInfo::getIpAddress, logPageQuery.getIpAddr());
        if (logPageQuery.getRequestEndTime() != null && logPageQuery.getRequestStartTime() != null)
            logInfoLambdaQueryWrapper.between(LogInfo::getRequestTime, logPageQuery.getRequestStartTime(), logPageQuery.getRequestEndTime());
        logInfoLambdaQueryWrapper.orderByDesc(LogInfo::getId); // 查询一般看最新的，故此处使用id逆序
        Page<LogInfo> logInfoPage = logInfoMapper.selectPage(new Page<>(logPageQuery.getCurPage(), logPageQuery.getPageSize()), logInfoLambdaQueryWrapper);
        return Result.ok(logInfoPage);
    }

    @DeleteMapping("/delete/{id}")
    @ApiOperation(value = "根据ID删除日志", notes = "根据ID删除日志")
    public Result<String> deleteLog(@PathVariable String id){
        logInfoMapper.deleteById(id);
        return Result.ok("删除成功");
    }

    @PostMapping("/delete/batch")
    @ApiOperation(value = "批量删除日志", notes = "批量删除日志")
    public Result<String> deleteLog(@RequestBody LogDeleteQuery logDeleteQuery){
        logInfoMapper.delete(new QueryWrapper<LogInfo>().lambda().lt(LogInfo::getRequestTime,logDeleteQuery.getDatetime()));
        return Result.ok("批量删除成功");
    }

    @GetMapping("/all/visit")
    @ApiOperation(value = "总访问量", notes = "总访问量")
    public Result<Integer> getAllVisit(){
        String[] split = statisticVisitInterface.split(",");
        List<String> interfacesList = Arrays.asList(split);
        Integer count = logInfoMapper.selectCount(new LambdaQueryWrapper<LogInfo>().in(LogInfo::getRequestAddress, interfacesList));
        return Result.ok(count);
    }

    @GetMapping("/department/visit")
    @ApiOperation(value = "部门访问量", notes = "部门访问量")
    public Result<List<DepartmentVisitStatisticVO>> getDepartmentVisit(@RequestParam(required = false, defaultValue = "7") Integer days){
        String[] split = statisticVisitInterface.split(",");
        List<String> interfacesList = Arrays.asList(split);
        List<DepartmentVisitStatisticVO> departmentVisit = logInfoMapper.getDepartmentVisit(interfacesList, days);
        if (CollectionUtils.isEmpty(departmentVisit)) return Result.fail("暂不存在任何访问");

        // 处理部门数据
        Map<Long, DepartmentDO> departmentDOMap = getDepartmentCache().stream().collect(Collectors.toMap(k->Long.valueOf(k.getId()), v -> v));
        for (DepartmentVisitStatisticVO departmentVisitStatisticVO : departmentVisit) {
            Long departmentId = departmentVisitStatisticVO.getDepartmentId();
            if (departmentId != null){
                DepartmentDO departmentDO = departmentDOMap.get(departmentId);
                if (departmentDO != null){
                    departmentVisitStatisticVO.setDepartmentName(departmentDO.getName());
                }else {  // 入库时存在部门id，但是部门后面被删除
                    departmentVisitStatisticVO.setDepartmentName("其它"); // 已删除的
                }
            }else {  // 入库时不存在部门id的
                departmentVisitStatisticVO.setDepartmentId(0L);
                departmentVisitStatisticVO.setDepartmentName("其它");
            }
        }
        return Result.ok(departmentVisit);
    }


    private List<DepartmentDO> getDepartmentCache(){
        Object o =  redisUtils.get(departmentCacheKey);
        if (o == null) {
            List<DepartmentDO> departmentDOS = departmentMapper.selectList(new LambdaQueryWrapper<DepartmentDO>().eq(DepartmentDO::getTypeCollection, departmentTypeCollection));
            redisUtils.set(departmentCacheKey, departmentDOS, 7L, TimeUnit.DAYS);
            return departmentDOS;
        }else {
            return (List<DepartmentDO>) o;
        }
    }


}
